package org.ns.tomdog.classloader;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ClassPath {

    private File classpath; // classpath
    private File libspath; // 库
    private Map<String, List<JarEnrtyWrapper>> jarEnrtyWrapperMap = new ConcurrentHashMap<>();

    public ClassPath(String classpath, String libspath) {
        this(classpath == null?null : new File(classpath), libspath == null ? null : new File(libspath));
    }
    public ClassPath(File classpath, File libspath) {
        this.classpath = classpath;
        this.libspath = libspath;
        init(classpath);
        init(libspath);
    }

    private void init(File path) {
        if (path == null || !path.exists()) {
            return;
        }
        File[] files = path.listFiles();
        for (File file : files) {
            if (file.getName().endsWith(".jar")) {
                try {
                    JarFile jarFile = new JarFile(file);
                    Enumeration<JarEntry> entries = jarFile.entries();
                    while (entries.hasMoreElements()) {
                        JarEntry jarEntry = entries.nextElement();
                        String entryName = jarEntry.getName();
                        JarEnrtyWrapper jarEnrtyWrapper = new JarEnrtyWrapper(jarFile, jarEntry);
                        List<JarEnrtyWrapper> jarEnrtyWrappers = jarEnrtyWrapperMap.get(entryName);
                        if (jarEnrtyWrappers == null) {
                            jarEnrtyWrappers = new ArrayList<>();
                            jarEnrtyWrapperMap.put(entryName, jarEnrtyWrappers);
                        }
                        jarEnrtyWrappers.add(jarEnrtyWrapper);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public File getClasspath() {
        return classpath;
    }

    public File getLibspath() {
        return libspath;
    }

    public URL getResource(String name) {
        try {
            if (classpath != null && classpath.exists()) {
                if (name == null || (name = name.trim()).isEmpty()) {
                    return classpath.toURI().toURL();
                }
                File file = new File(classpath, name);
                if (file.exists()) {
                    return file.toURI().toURL();
                }
            }
            List<JarEnrtyWrapper> jarEnrtyWrappers = jarEnrtyWrapperMap.get(name);
            if (jarEnrtyWrappers != null && jarEnrtyWrappers.size() > 0) {
                return jarEnrtyWrappers.get(0).getURL();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public Enumeration<URL> getResources(String name) throws IOException {
        try {
            List<URL> urls = new ArrayList<>();
            if (classpath != null && classpath.exists()) {
                File file = new File(classpath, name);
                if (file.exists()) {
                    urls.add(file.toURI().toURL());
                }
            }
            List<JarEnrtyWrapper> jarEnrtyWrappers = jarEnrtyWrapperMap.get(name);
            if (jarEnrtyWrappers != null && jarEnrtyWrappers.size() > 0) {
                for (JarEnrtyWrapper jarEnrtyWrapper : jarEnrtyWrappers) {
                    urls.add(jarEnrtyWrapper.getURL());
                }
            }
            Iterator<URL> iterator = urls.iterator();
            return new Enumeration<URL>() {
                @Override
                public boolean hasMoreElements() {
                    return iterator.hasNext();
                }

                @Override
                public URL nextElement() {
                    return iterator.next();
                }
            };
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
